package vip.xiaonuo.biz.modular.lancerGoods.service.impl;

import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import vip.xiaonuo.auth.core.pojo.SaBaseLoginUser;
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
import vip.xiaonuo.biz.core.config.AliPayConfig;
import vip.xiaonuo.biz.modular.lancerBrand.service.BizBrandService;
import vip.xiaonuo.biz.modular.lancerCoupon.entity.BizCoupon;
import vip.xiaonuo.biz.modular.lancerCoupon.service.BizCouponService;
import vip.xiaonuo.biz.modular.lancerFile.FileService;
import vip.xiaonuo.biz.modular.lancerGoodsBox.service.BizGoodsBoxService;
import vip.xiaonuo.biz.modular.lancerGoodsTag.entity.BizGoodsTag;
import vip.xiaonuo.biz.modular.lancerGoodsTag.service.BizGoodsTagService;
import vip.xiaonuo.biz.modular.lancerGoodskill.service.BizGoodsKillService;
import vip.xiaonuo.biz.modular.lancerUserGoods.entity.BizUserGoods;
import vip.xiaonuo.biz.modular.lancerUserGoods.service.BizUserGoodsService;
import vip.xiaonuo.biz.modular.lancerUsercoupon.entity.BizUserCoupon;
import vip.xiaonuo.biz.modular.lancerUsercoupon.service.BizUserCouponService;
import vip.xiaonuo.common.pojo.DbEnum;
import vip.xiaonuo.biz.modular.pojo.domain.*;
import vip.xiaonuo.biz.modular.lancerGoods.service.BizGoodsService;
import vip.xiaonuo.biz.modular.mapper.BizGoodsMapper;
import org.springframework.stereotype.Service;
import vip.xiaonuo.biz.modular.pojo.dto.add.GoodsAddDTO;
import vip.xiaonuo.biz.modular.pojo.dto.common.CommonDeleteDTO;
import vip.xiaonuo.biz.modular.pojo.dto.common.CommonDetailDTO;
import vip.xiaonuo.biz.modular.pojo.dto.edit.AttributeEdit;
import vip.xiaonuo.biz.modular.pojo.dto.edit.GoodsEditDTO;
import vip.xiaonuo.biz.modular.pojo.dto.edit.GoodsEditStatusDTO;
import vip.xiaonuo.biz.modular.pojo.dto.page.GoodsPageDTO;
import vip.xiaonuo.biz.modular.pojo.vo.KV;
import vip.xiaonuo.biz.modular.service.BizGoodsAttributeService;
import vip.xiaonuo.biz.modular.service.BizGoodsTagRefService;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;
import vip.xiaonuo.dev.modular.file.provider.DevFileApiProvider;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author LancerAdmin
 * @description 针对表【biz_goods(商品信息)】的数据库操作Service实现
 * @createDate 2024-02-29 14:54:24
 */
@Service
public class BizGoodsServiceImpl extends ServiceImpl<BizGoodsMapper, BizGoods>
        implements BizGoodsService {
    @Resource
    private AliPayConfig aliPayConfig;
    private static final String FORMAT = "JSON";
    private static final String CHARSET = "UTF-8";
    //签名方式
    private static final String SIGN_TYPE = "RSA2";

    @Autowired
    FileService fileService;
    @Autowired
    BizBrandService brandService;

    @Autowired
    BizGoodsTagService tagService;

    @Autowired
    BizGoodsAttributeService attributeService;
    @Resource
    private DevFileApiProvider devFileApi;
    @Override
    public BizGoods detail(CommonDetailDTO dto) {
        String id = dto.getId();
        BizGoods bizGoods = this.getById(id);

        // 查询商品标签
        bizGoods.setTagList(tagService.getTagByGoodsId(id).stream().map(BizGoodsTag::getTagName).collect(Collectors.toList()));
        // 查询商品属性
        bizGoods.setAttributeList(attributeService.getAttributeByGoodsId(id));
        // 商品图片分割
        String goodsImgUrls = bizGoods.getGoodsImgUrls();
        List<String> imgUrlList = JSON.parseArray(goodsImgUrls, String.class);
        bizGoods.setImgUrlList(imgUrlList);

        return bizGoods;
    }


    @Override
    public void redGoodsNumberByGoodsId(String id) {
        this.getBaseMapper().redGoodsNumberByGoodsId(id);
    }

    @Override
    public void insGoodsNumberByGoodsId(String id) {
        this.getBaseMapper().incGoodsNumberByGoodsId(id);
    }
    @Override
    @Transactional
    public void add(GoodsAddDTO dto) {
        MultipartFile[] imgUrls = dto.getGoodsImgUrls();

        BizGoods obj = new BizGoods();

        if (ObjectUtil.isNotEmpty(imgUrls)) {
            List<String> imgUrlList = new ArrayList<>(imgUrls.length);
            for (MultipartFile imgUrl : imgUrls) {
                String minioWordUrl = devFileApi.storageFileWithReturnUrlMinio(imgUrl);
                imgUrlList.add(minioWordUrl);
            }
            obj.setGoodsImgUrls(JSON.toJSONString(imgUrlList));
        } else {
            throw new CommonException("上传的照片不能为空！");
        }

        obj.setBrandId(StpLoginUserUtil.getLoginUser().getId())
                .setGoodsDetails(dto.getGoodsDetails())
                .setGoodsName(dto.getGoodsName())
                .setGoodsBoxId(dto.getGoodsBoxId())
                .setSellingPoint(dto.getSellingPoint())
                .setActualStockCount(dto.getActualStockCount())
                .setAvailableStockCount(dto.getAvailableStockCount())
                .setGoodsPriceFee(dto.getGoodsPriceFee())
                .setGoodsMarketPriceFee(dto.getGoodsMarketPriceFee())
                .setGoodsSort(dto.getGoodsSort())
                .setSellCount(0)
                .setGoodsStatus(DbEnum.GoodsStatus.NORMAL.getValue());
        this.save(obj);
        String goodsId = obj.getId();

        List<String> tagList = dto.getTagList();
        // 全量新增
        TagAllAdd(tagList, goodsId);

        // 商品盒子能量+1
        bizGoodsBoxService.incEnergy(dto.getGoodsBoxId());
    }

    @Override
    @Transactional
    public void delete(List<CommonDeleteDTO> dto) {
        List<String> idList = CollStreamUtil.toList(dto, CommonDeleteDTO::getId);
        String id = bizGoodsBoxService.getObjByGoodsId(idList.get(0)).getId();
        for (String s : idList) {
            // 商品盒子能量-1
            bizGoodsBoxService.redEnergy(id);
        }
        // 删除类型
        this.removeBatchByIds(idList);
    }

    @Override
    @Transactional
    public void edit(GoodsEditDTO dto) {
        String goodsId = dto.getId();
        BizGoods obj = new BizGoods();
        String isChangeImgs = dto.getIsChangeImgs();
        DbEnum.YOrN.validate(isChangeImgs);
        // 状态
        String goodsStatus = dto.getGoodsStatus();
        DbEnum.GoodsStatus.validate(goodsStatus);
        obj.setId(goodsId)
                .setGoodsStatus(goodsStatus)
                .setBrandId(StpLoginUserUtil.getLoginUser().getId())
                .setGoodsDetails(dto.getGoodsDetails())
                .setGoodsName(dto.getGoodsName())
                .setGoodsBoxId(dto.getGoodsBoxId())
                .setSellingPoint(dto.getSellingPoint())
                .setActualStockCount(dto.getActualStockCount())
                .setAvailableStockCount(dto.getAvailableStockCount())
                .setGoodsMarketPriceFee(dto.getGoodsMarketPriceFee())
                .setGoodsPriceFee(dto.getGoodsPriceFee())
                .setGoodsSort(dto.getGoodsSort());
        http:
//192.168.72.1:9000/myfile/2024/3/13/1767927526361993218.png
        if (isChangeImgs.equals(DbEnum.YOrN.YES.getValue())) {
            MultipartFile[] imgUrls = dto.getGoodsImgUrls();
            if (ObjectUtil.isNotEmpty(imgUrls)) {
                List<String> imgUrlList = new ArrayList<>(imgUrls.length);
                for (MultipartFile imgUrl : imgUrls) {
                    String minioWordUrl = devFileApi.storageFileWithReturnUrlMinio(imgUrl);
                    imgUrlList.add(minioWordUrl);
                }
                obj.setGoodsImgUrls(JSON.toJSONString(imgUrlList));
            }
        }
        this.updateById(obj);

        List<String> tagList = dto.getTagList();
        // 全量删除
        LambdaQueryWrapper<BizGoodsTagRef> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BizGoodsTagRef::getGoodsId, dto.getGoodsBoxId());
        tagRefService.remove(queryWrapper);
        // 全量新增
        TagAllAdd(tagList, goodsId);

        // 商品盒子能量+1
        bizGoodsBoxService.incEnergy(dto.getGoodsBoxId());
    }


    // 全量新增
    public void TagAllAdd(List<String> tagList, String goodsId) {
        List<BizGoodsTagRef> tagRefs = new ArrayList<>(tagList.size());
        for (String s : tagList) {
            String tagId = tagService.getTagIdByName(s);
            // 没有的就创建
            if (ObjectUtil.isEmpty(tagId)) {
                BizGoodsTag bizGoodsTag = new BizGoodsTag();
                bizGoodsTag.setTagName(s).setCurrEnergy(0);
                tagService.save(bizGoodsTag);
                tagId = bizGoodsTag.getId();
            }
            BizGoodsTagRef ref = new BizGoodsTagRef();
            ref.setGoodsId(goodsId)
                    .setTagId(tagId);
            tagRefs.add(ref);
        }
        tagRefService.saveBatch(tagRefs);
    }

    @Autowired
    BizGoodsTagRefService tagRefService;

    @Override
    public void editStatus(GoodsEditStatusDTO dto) {
        String goodsStatus = dto.getGoodsStatus();
        DbEnum.GoodsStatus.validate(goodsStatus);
        BizGoods goods = new BizGoods();
        goods.setId(dto.getId()).setGoodsStatus(goodsStatus);
        this.updateById(goods);
    }

    @Override
    public Page<BizGoods> pageLAdmin(GoodsPageDTO dto) {
        String goodsStatus = dto.getGoodsStatus();
        if (ObjectUtil.isEmpty(goodsStatus)) {
            goodsStatus = DbEnum.GoodsStatus.NORMAL.getValue();
        }
        DbEnum.GoodsStatus.validate(goodsStatus);
        LambdaQueryWrapper<BizGoods> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(ObjectUtil.isNotEmpty(dto.getGoodsBoxId()),
                        BizGoods::getGoodsBoxId,
                        dto.getGoodsBoxId())
                .eq(ObjectUtil.isNotEmpty(goodsStatus),
                        BizGoods::getGoodsStatus,
                        goodsStatus)
                .like(ObjectUtil.isNotEmpty(dto.getGoodsName()),
                        BizGoods::getGoodsName,
                        dto.getGoodsName())
                .like(ObjectUtil.isNotEmpty(dto.getSellingPoint()),
                        BizGoods::getSellingPoint,
                        dto.getSellingPoint())
                .orderByDesc(BizGoods::getCreateTime);
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }


    @Autowired
    BizGoodsBoxService bizGoodsBoxService;

    @Override
    public List<BizGoods> getAllGoodsByGoodsBox(GoodsPageDTO dto) {
        LambdaQueryWrapper<BizGoods> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(BizGoods::getId).eq(BizGoods::getGoodsBoxId, dto.getGoodsBoxId())
                .eq(BizGoods::getGoodsStatus, DbEnum.GoodsStatus.NORMAL.getValue());
        List<String> IdList = this.list(queryWrapper).stream().map(BizGoods::getId).collect(Collectors.toList());
        List<BizGoods> goodsDetailsList = new ArrayList<>(IdList.size());
        for (String s : IdList) {
            goodsDetailsList.add(this.detail(new CommonDetailDTO(s)));
        }
        return goodsDetailsList;
    }

    @Override
    public Page<BizGoods> pageLClient(GoodsPageDTO dto) {
        LambdaQueryWrapper<BizGoods> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .like(ObjectUtil.isNotEmpty(dto.getGoodsName()),
                        BizGoods::getGoodsName,
                        dto.getGoodsName())
                .like(ObjectUtil.isNotEmpty(dto.getSellingPoint()),
                        BizGoods::getSellingPoint,
                        dto.getSellingPoint())
                .orderByDesc(BizGoods::getCreateTime);
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }

    @Override
    public List<KV> INTRODUCTIONAttr(CommonDetailDTO dto) {
        List<BizGoodsAttribute> byGoodsId = attributeService.getAttributeINTRODUCTIONByGoodsId(dto.getId());
        return byGoodsId.stream().map(x -> {
            KV kv = new KV();
            kv.setKey(x.getAttributeKey());
            kv.setVal(x.getAttributeVal());
            return kv;
        }).collect(Collectors.toList());
    }

    @Override
    public List<KV> STANDARDSAttr(CommonDetailDTO dto) {
        List<BizGoodsAttribute> byGoodsId = attributeService.getAttributeSTANDARDSByGoodsId(dto.getId());
        return byGoodsId.stream().map(x -> {
            KV kv = new KV();
            kv.setKey(x.getAttributeKey());
            kv.setVal(x.getAttributeVal());
            return kv;
        }).collect(Collectors.toList());
    }

    public void BatchAddAttribute(List<KV> attributeList, String goodsId, String type) {
        List<BizGoodsAttribute> collect = attributeList.stream().map(x -> {
            BizGoodsAttribute attribute = new BizGoodsAttribute();
            attribute.setGoodsId(goodsId).setAttributeKey(x.getKey())
                    .setAttributeVal(x.getVal())
                    .setAttrType(type);
            return attribute;
        }).collect(Collectors.toList());
        attributeService.saveBatch(collect);
    }

    @Override
    public void UpdateINTRODUCTIONAttr(AttributeEdit dto) {
        String goodsId = dto.getId();
        // 删除所有
        LambdaQueryWrapper<BizGoodsAttribute> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BizGoodsAttribute::getGoodsId, goodsId)
                .eq(BizGoodsAttribute::getAttrType, DbEnum.GoodsAttr.INTRODUCTION.getValue());
        attributeService.remove(queryWrapper);
        List<KV> attributeList = dto.getAttributeList();
        // 新增
        BatchAddAttribute(attributeList, goodsId, DbEnum.GoodsAttr.INTRODUCTION.getValue());
    }

    @Override
    public void UpdateSTANDARDSAttr(AttributeEdit dto) {
        String goodsId = dto.getId();
        // 删除所有
        LambdaQueryWrapper<BizGoodsAttribute> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BizGoodsAttribute::getGoodsId, goodsId)
                .eq(BizGoodsAttribute::getAttrType, DbEnum.GoodsAttr.STANDARDS.getValue());
        attributeService.remove(queryWrapper);
        List<KV> attributeList = dto.getAttributeList();
        // 新增
        BatchAddAttribute(attributeList, goodsId, DbEnum.GoodsAttr.STANDARDS.getValue());
    }

    // B 端方法：

    @Override
    public Page<BizGoods> pageBus(GoodsPageDTO dto) {
        String goodsStatus = dto.getGoodsStatus();
        if (ObjectUtil.isEmpty(goodsStatus)) {
            goodsStatus = DbEnum.GoodsStatus.NORMAL.getValue();
        }
        DbEnum.GoodsStatus.validate(goodsStatus);
        LambdaQueryWrapper<BizGoods> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(BizGoods::getBrandId, StpLoginUserUtil.getLoginUser().getId())
                .eq(ObjectUtil.isNotEmpty(dto.getGoodsBoxId()),
                        BizGoods::getGoodsBoxId,
                        dto.getGoodsBoxId())
                .eq(ObjectUtil.isNotEmpty(goodsStatus),
                        BizGoods::getGoodsStatus,
                        goodsStatus)
                .like(ObjectUtil.isNotEmpty(dto.getGoodsName()),
                        BizGoods::getGoodsName,
                        dto.getGoodsName())
                .like(ObjectUtil.isNotEmpty(dto.getSellingPoint()),
                        BizGoods::getSellingPoint,
                        dto.getSellingPoint())
                .orderByDesc(BizGoods::getCreateTime);

        return this.page(CommonPageRequest.defaultPage(), queryWrapper);

    }

    @Autowired
    BizUserGoodsService userGoodsService;
    @Autowired
    BizGoodsService goodsService;

    @Autowired
    BizGoodsKillService killService;

    /**
     * 购买商品
     *
     * @param id    id
     * @param count 计数
     */
    @Override
    public String buyGoods(String id, Integer count) {
        BizUserGoods bizUserGoods = new BizUserGoods();
        SaBaseLoginUser loginUser = StpLoginUserUtil.getLoginUser();
        BizGoodsBox box = bizGoodsBoxService.getObjByGoodsId(id);
        // 商品
        BizGoods bizGoods = goodsService.getById(id);
        bizUserGoods
                .setCount(count)
                .setStatus(DbEnum.ORDER_STATUS.NO_PAY.getValue())
                .setGoodsId(bizGoods.getId())
                .setGoodsName(bizGoods.getGoodsName());
        // 商品盒子
        bizUserGoods.setGoodsBoxId(box.getId())
                .setGoodsBoxName(box.getGoodsBoxName());
        // 品牌信息
        bizUserGoods.setBrandId(box.getBrandId())
                .setBrandName(box.getBrandName());
        // 消费者信息
        bizUserGoods.setCreateUser(loginUser.getId())
                .setUserName(loginUser.getName());
        String categoryId = box.getCategoryId();
        // 类型
        bizUserGoods.setCategoryId(categoryId);
        // 金钱计算
        Integer payMoney = getPayMoney(bizGoods, count, loginUser.getId());
        bizUserGoods.setPayMoney(payMoney);
        userGoodsService.save(bizUserGoods);
        // 直接返回生成的订单id
        return bizUserGoods.getId();
    }
    // 减少库存
    public void redOrderNumber(BizUserGoods bizUserGoods){
        // TODO: 真实场景下 新增订单
        // 商品数量减少
        String boxId = bizUserGoods.getGoodsBoxId();
        goodsService.redGoodsNumberByGoodsId(bizUserGoods.getGoodsId());
        // 判断是否有秒杀活动
        boolean x = killService.isDoingKill(boxId);
        if (x) {
            for (int i = 0; i < bizUserGoods.getCount(); i++) {
                // 秒杀-1
                killService.redGoodsNumberByBoxId(boxId);
            }
        }
    }
    // 增加库存
    public void incOrderNumber(BizUserGoods bizUserGoods){
        // 商品数量增加
        String boxId = bizUserGoods.getGoodsBoxId();
        goodsService.insGoodsNumberByGoodsId(bizUserGoods.getGoodsId());
        // 判断是否有秒杀活动
        boolean x = killService.isDoingKill(boxId);
        if (x) {
            for (int i = 0; i < bizUserGoods.getCount(); i++) {
                // 秒杀-1
                killService.incGoodsNumberByBoxId(boxId);
            }
        }
    }
    @Override
    public void buyGoodsByAliPayAndOrderId(String orderId, HttpServletResponse httpResponse) {
        // 1 获取订单
        BizUserGoods bizUserGoods = userGoodsService.getById(orderId);
        // 2 发送支付宝请求
        sendPay(bizUserGoods,httpResponse);
    }
    // 发送支付宝请求
    public void sendPay(BizUserGoods bizUserGoods,HttpServletResponse httpResponse){
        // 请求pay
        // 1. 创建Client，通用SDK提供的Client，负责调用支付宝的API
        AlipayClient alipayClient = new DefaultAlipayClient(
                aliPayConfig.getGateway(),
                aliPayConfig.getAppId(),
                aliPayConfig.getPrivateKey(),
                FORMAT,
                CHARSET,
                aliPayConfig.getPublicKey(),
                SIGN_TYPE);

        // 2. 创建 Request并设置Request参数
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();  // 发送请求的 Request类
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());
        JSONObject bizContent = new JSONObject();
        // 生成的订单编号
        bizContent.put("out_trade_no", bizUserGoods.getId());
        // 订单的总金额
        bizContent.put("total_amount", bizUserGoods.getPayMoney());
        // 支付的名称
        bizContent.put("subject", bizUserGoods.getGoodsName());
        // 固定配置
        bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");

        request.setBizContent(bizContent.toString());
        // 设置支付完成后的跳转地址
        request.setReturnUrl("http://192.168.75.1:3101/GoodsDetails?id=" + bizUserGoods.getGoodsBoxId());

        // 执行请求，拿到响应的结果，返回给浏览器
        String form = "";
        try {
            // 调用SDK生成表单
            form = alipayClient.pageExecute(request).getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        httpResponse.setContentType("text/html;charset=" + CHARSET);
        try {
            // 直接将完整的表单html输出到页面
            httpResponse.getWriter().write(form);
            httpResponse.getWriter().flush();
            httpResponse.getWriter().close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    @Override
    public void buyGoodsByAliPay(String id, Integer count, HttpServletResponse httpResponse) {
        // 1 生成 订单id
        String userGoodsId = buyGoods(id, count);
        // 2 获取订单
        BizUserGoods bizUserGoods = userGoodsService.getById(userGoodsId);
        // 3 减少库存
        redOrderNumber(bizUserGoods);
        // 4 设置订单超时取消支付
        addUnPaid(userGoodsId);
        // 5 发送支付宝请求
        sendPay(bizUserGoods,httpResponse);
    }

    @Override
    public void payBack(HttpServletRequest request) {
        if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
            System.out.println("=========支付宝异步回调========");
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                params.put(name, request.getParameter(name));
                // System.out.println(name + " = " + request.getParameter(name));
            }

            String tradeNo = params.get("out_trade_no");
            String gmtPayment = params.get("gmt_payment");
            String alipayTradeNo = params.get("trade_no");

            String sign = params.get("sign");
            String content = AlipaySignature.getSignCheckContentV1(params);
            // 验证签名
            boolean checkSignature = false;
            try {
                checkSignature = AlipaySignature.rsa256CheckContent(content, sign,
                        aliPayConfig.getPublicKey(), "UTF-8");
            } catch (AlipayApiException e) {
                throw new RuntimeException(e);
            }
            // 支付宝验签
            if (checkSignature) {
                // 验签通过
//                System.out.println("交易名称: " + params.get("subject"));
//                System.out.println("交易状态: " + params.get("trade_status"));
//                System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
//                System.out.println("商户订单号: " + params.get("out_trade_no"));
//                System.out.println("交易金额: " + params.get("total_amount"));
//                System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
//                System.out.println("买家付款时间: " + params.get("gmt_payment"));
//                System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));
                BizUserGoods bizUserGoods = userGoodsService.getById(tradeNo);



                // 订单状态改变
                LambdaUpdateWrapper<BizUserGoods> updateWrapper=new LambdaUpdateWrapper<>();
                // 支付成功状态
                updateWrapper.eq(BizUserGoods::getId,bizUserGoods.getId())
                                .set(BizUserGoods::getStatus,DbEnum.ORDER_STATUS.PAY.getValue());
                userGoodsService.update(updateWrapper);

            }
        }
    }



    @Autowired
    BizUserCouponService userCouponService;

    @Autowired
    BizCouponService couponService;


    public Integer getPayMoney(BizGoods bizGoods, Integer count, String userId) {
        // 查询是否存在优惠券
        LambdaQueryWrapper<BizUserCoupon> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .select(BizUserCoupon::getCouponId)
                .eq(BizUserCoupon::getUserId, userId);
        List<BizUserCoupon> bizUserCoupons = userCouponService.list(queryWrapper);
        List<String> couponIdList = bizUserCoupons.stream().map(BizUserCoupon::getCouponId).collect(Collectors.toList());
        int originMoney = bizGoods.getGoodsPriceFee() * count;
        // 查询当前商品下是否存在优惠券
        if (ObjectUtil.isEmpty(couponIdList)) {
            return originMoney;
        }
        LambdaQueryWrapper<BizCoupon> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.in(BizCoupon::getId, couponIdList);
        long count1 = couponService.count(queryWrapper1);
        if (count1 < 1) {
            return originMoney;
        }
        // 存在优惠券
        // 计算总价
        List<BizCoupon> bizCouponList = couponService.list(queryWrapper1);
        for (BizCoupon coupon : bizCouponList) {
            // 判断是否合规
            Integer fullMoney = coupon.getFullMoney();
            // 达到漫减金额
            if (originMoney < fullMoney) {
                continue;
            }
            // 减后最低为0
            if (originMoney - coupon.getReductionMoney() < 0) {
                // 当前的优惠券就可以减到0了，就终止遍历优惠券
                originMoney = originMoney - coupon.getReductionMoney();
                // 删除用户的优惠券
                LambdaQueryWrapper<BizUserCoupon> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(BizUserCoupon::getCouponId, coupon.getId());
                userCouponService.remove(lambdaQueryWrapper);
                break;
            }
            originMoney = originMoney - coupon.getReductionMoney();
            // 删除用户的优惠券
            LambdaQueryWrapper<BizUserCoupon> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(BizUserCoupon::getCouponId, coupon.getId());
            userCouponService.remove(lambdaQueryWrapper);
        }
        return originMoney;
    }

    @Resource
    RedissonClient redissonClient;
    @Override
    // 创建未付款的订单id到Redis中
    public void addUnPaid(String orderId){
        RBlockingQueue<String> blockingFairQueue = redissonClient.getBlockingQueue("orderQueue");
        RDelayedQueue<String> delayedQueue = redissonClient.getDelayedQueue(blockingFairQueue);
        delayedQueue.offer(orderId,15, TimeUnit.MINUTES);
    }
    // 是否支付
    @Override
    public boolean isPaid(String orderId){
        return userGoodsService.isPaid(orderId);
    }
    // 订单关闭
    @Override
    public void closeOrder(String orderId) {
        BizUserGoods bizUserGoods = userGoodsService.getById(orderId);
        // 1 商品+1
        // 2 如果存在秒杀 +1
        incOrderNumber(bizUserGoods);
        // 3 更改订单状态
        LambdaUpdateWrapper<BizUserGoods> updateWrapper=new LambdaUpdateWrapper<>();
        updateWrapper.set(BizUserGoods::getStatus,DbEnum.ORDER_STATUS.PAY_CLOSE.getValue())
                .eq(BizUserGoods::getId,orderId);
        userGoodsService.update(updateWrapper);
    }


}